﻿using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;

namespace Drive.DbAccess
{

    public class DTable
    {
        public DTable()
        {
            this.Columns = new List<DColumn>();
            this.Rows = new List<DRow>();
        }

        public List<DColumn> Columns { get; set; }
        public List<DRow> Rows { get; set; }
        public string Sql { get; set; }

        public string TableName { get; set; }

        public List<T> ToModel<T>() where T : new()
        {
            var list = new List<T>();

            foreach (var row in Rows)
            {
                var item = new T();
                foreach (var val in row.ItemArray)
                {
                    foreach (var prop in typeof(T).GetProperties())
                    {
                        if (prop.Name.Equals(val.Column.Name, StringComparison.OrdinalIgnoreCase))
                        {
                            var convertedVal = ValueConvert.Convert(val.Value, prop.PropertyType);
                            try
                            {
                                prop.SetValue(item, convertedVal);
                            }
                            catch (Exception ex)
                            {
                                Debugger.Break();
                            }
                        }
                    }
                }
                list.Add(item);
            }
            return list;
        }
    }

    [DebuggerDisplay("{ItemArray}")]
    public class DRow
    {
        public List<DItem> ItemArray { get; set; }
        public object Get(string name)
        {
            var item = ItemArray.FirstOrDefault(x => string.Equals(x.Column.Name, name, StringComparison.OrdinalIgnoreCase));
            if (item == null)
            {
                throw new KeyNotFoundException($"查询结果中没有名称为\"{name}\"的列");
            }
            return item.Value;
        }

        public object Get(int index)
        {
            var item = ItemArray[index];
            return item.Value;
        }

        public string GetString(string name)
        {
            var obj = Get(name);
            if (obj == null || obj == DBNull.Value)
            {
                return default(string);
            }
            return obj.ToString();
        }

        public string GetString(int index)
        {
            var obj = Get(index);
            if (obj == null || obj == DBNull.Value)
            {
                return default(string);
            }
            return obj.ToString();
        }


        public bool GetBoolean(string name)
        {
            var obj = Get(name);
            if (obj == null || obj == DBNull.Value)
            {
                return default(bool);
            }
            return bool.Parse(obj.ToString());
        }

        public DateTime GetDateTime(string name)
        {
            var obj = Get(name);
            if (obj == null || obj == DBNull.Value)
            {
                return default(DateTime);
            }
            return DateTime.Parse(obj.ToString());
        }

        public int GetInt(string name)
        {
            var obj = Get(name);
            if (obj == null || obj == DBNull.Value)
            {
                return default(int);
            }
            return int.Parse(obj.ToString());
        }

        public Guid GetGuid(string name)
        {
            var obj = Get(name);
            if (obj == null || obj == DBNull.Value)
            {
                return default(Guid);
            }
            return Guid.Parse(obj.ToString());
        }

        public double GetDouble(string name)
        {
            var obj = Get(name);
            if (obj == null || obj == DBNull.Value)
            {
                return default(double);
            }
            return double.Parse(obj.ToString());
        }
    }

    public class DItem
    {
        [DebuggerDisplay("{Column.Name} {Value}")]
        public DColumn Column { get; set; }
        public object Value { get; set; }

        public override string ToString()
        {
            return $"{Column.Name} {Value}".ToString();
        }
    }

    public struct DColumn
    {
        public string Name { get; set; }
        public Type Type { get; set; }
    }
}
